// This File is part of the "nyaqt" Project
// 
// Copyright  2009 sometmes@gmail.com
// All rights reserved
// 
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Collections.Specialized;
using Microsoft.Win32;
using System.IO;
using EnvDTE80;

namespace SmAddin.Commands
{
    class DiffCommand
    {
        static string _tmergeRegKey = @"SOFTWARE\TortoiseSVN";
        static string _tmergeRegValue = "TMergePath";
        static string _tmergePath = null; //@"Y:\TortoiseMerge\TortoiseMerge.exe";

        static string _araxisMergeRegKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\merge.exe";
        static string _araxisMergeRegValue = "";
        static string _araxisMergePath = null;

        static string _selectedTwoDiffToolValue = "TwoDiffToolName";
        static string _alternateTwoDiffToolValue = "TwoDiffToolNameAlternate";
        static string _selectedThreeDiffToolValue = "ThreeDiffToolName";
        static string _alternateThreeDiffToolValue = "ThreeDiffToolNameAlternate";

        DTE2 _dte;

        public DTE2 DTE
        {
            get { return _dte; }
            set { _dte = value; }
        }


        public DiffCommand(DTE2 dte)
        {
            this.DTE = dte;

            RegistryKey key;

            // Compare tools
            using (key = Registry.LocalMachine.OpenSubKey(_tmergeRegKey))
            {
                if (key != null)
                    _tmergePath = key.GetValue(_tmergeRegValue) as string;
                else
                {
                    string programFiles = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
                    string tmerge = Path.Combine(programFiles,@"TortoiseSVN\bin\TortoiseMerge.exe");
                    if (File.Exists(tmerge))
                        _tmergePath = tmerge;
                }
            }

            using (key = Registry.LocalMachine.OpenSubKey(_araxisMergeRegKey))
            {
                if (key != null)
                {
                    _araxisMergePath = key.GetValue(_araxisMergeRegValue) as string;
                    _araxisMergePath = _araxisMergePath.Replace("\"","");
                    if (_araxisMergePath != null)
                        _araxisMergePath = Path.Combine(
                            Path.GetDirectoryName(_araxisMergePath),
                            "compare.exe");
                }
            }

            _tfPath = Path.Combine(CommandPromptCommand.GetVsPath(DTE), "tf.exe");


            // Selected tools
            string selectedTwoDiffToolValue;
            string alternateTwoDiffToolValue;
            string selectedThreeDiffToolValue;
            string alternateThreeDiffToolValue;

            using (key = Registry.CurrentUser.OpenSubKey(Konstants.PluginRegKey, true))
            {
                if (key == null)
                    key = Registry.CurrentUser.CreateSubKey(Konstants.PluginRegKey);
                selectedTwoDiffToolValue = key.GetValue(_selectedTwoDiffToolValue) as string;
                alternateTwoDiffToolValue = key.GetValue(_alternateTwoDiffToolValue) as string;
                selectedThreeDiffToolValue = key.GetValue(_selectedThreeDiffToolValue) as string;
                alternateThreeDiffToolValue = key.GetValue(_alternateThreeDiffToolValue) as string;
            }


            _twoFileCompareTools = new List<Commands.DiffTool>();
            Commands.DiffTool tool;
            if (_tmergePath != null)
            {
                tool = new DiffTool();
                tool.Name = "TortoiseMerge";
                tool.Program = _tmergePath;
                tool.Arguments = " %theirs% %mine%";
                _twoFileCompareTools.Add(tool);

                _selectedTwoDiffTool = tool;
            }

            if (_araxisMergePath != null)
            {
                tool = new DiffTool();
                tool.Name = "AraxisMerge";
                tool.Program = _araxisMergePath;
                tool.Arguments = " %theirs% %mine%";
                _twoFileCompareTools.Add(tool);

                _alternateTwoDiffTool = tool;
            }

            if (File.Exists(_tfPath))
            {
                tool = new DiffTool();
                tool.Name = "Team Foundation Diff";
                tool.Program = _tfPath;
                tool.Arguments = " diff %theirs% %mine%";
                _twoFileCompareTools.Add(tool);
            }


            _threeFileCompareTools = new List<Commands.DiffTool>();
            if (_tmergePath != null)
            {
                tool = new DiffTool();
                tool.Name = "TortoiseMerge";
                tool.Program = _tmergePath;
                tool.Arguments = " %base% %theirs% %mine%";
                _threeFileCompareTools.Add(tool);

                _selectedThreeDiffTool = tool;
            }

            if (_araxisMergePath != null)
            {
                tool = new DiffTool();
                tool.Name = "AraxisMerge";
                tool.Program = _araxisMergePath;
                tool.Arguments = " /a1 /3 %base% %theirs% %mine%";
                _threeFileCompareTools.Add(tool);

                _alternateThreeDiffTool = tool;
            }

            //tool = new DiffTool();
            //tool.Name = "Team Foundation Diff";
            //tool.Program = "tf.exe";
            //_threeFileCompareTools.Add(tool);


            foreach (DiffTool t in _twoFileCompareTools)
            {
                if (t.Name == selectedTwoDiffToolValue)
                    _selectedTwoDiffTool = t;

                if (t.Name == alternateTwoDiffToolValue)
                    _alternateTwoDiffTool = t;
            }

            foreach (DiffTool t in _threeFileCompareTools)
            {
                if (t.Name == selectedThreeDiffToolValue)
                    _selectedThreeDiffTool = t;

                if (t.Name == alternateThreeDiffToolValue)
                    _alternateThreeDiffTool = t;
            }
        }

        Commands.DiffTool _selectedTwoDiffTool;

        public Commands.DiffTool SelectedTwoDiffTool
        {
            get { return _selectedTwoDiffTool; }
            set
            {
                _selectedTwoDiffTool = value;
                if (value != null)
                {
                    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Konstants.PluginRegKey, true))
                    {
                        key.SetValue(_selectedTwoDiffToolValue, value.Name);
                    }

                }
            }
        }

        Commands.DiffTool _selectedThreeDiffTool;

        public Commands.DiffTool SelectedThreeDiffTool
        {
            get { return _selectedThreeDiffTool; }
            set
            {
                _selectedThreeDiffTool = value;
                if (value != null)
                {
                    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Konstants.PluginRegKey, true))
                    {
                        key.SetValue(_selectedThreeDiffToolValue, value.Name);
                    }

                }
            }
        }

        Commands.DiffTool _alternateTwoDiffTool;

        public Commands.DiffTool AlternateTwoDiffTool
        {
            get { return _alternateTwoDiffTool; }
            set
            {
                _alternateTwoDiffTool = value;
                if (value != null)
                {
                    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Konstants.PluginRegKey, true))
                    {
                        key.SetValue(_alternateTwoDiffToolValue, value.Name);
                    }
                }
            }
        }

        Commands.DiffTool _alternateThreeDiffTool;

        public Commands.DiffTool AlternateThreeDiffTool
        {
            get { return _alternateThreeDiffTool; }
            set
            {
                _alternateThreeDiffTool = value;
                if (value != null)
                {
                    using (RegistryKey key = Registry.CurrentUser.OpenSubKey(Konstants.PluginRegKey, true))
                    {
                        key.SetValue(_alternateThreeDiffToolValue, value.Name);
                    }
                }
            }
        }

        List<Commands.DiffTool> _twoFileCompareTools;

        public List<Commands.DiffTool> TwoFileCompareTools
        {
            get
            {
                return _twoFileCompareTools;
            }
        }

        List<Commands.DiffTool> _threeFileCompareTools;
        private string _tfPath;

        public List<Commands.DiffTool> ThreeFileCompareTools
        {
            get
            {
                return _threeFileCompareTools;
            }
        }

        public void CompareTwoFiles(string path1, string path2, bool alternateTool)
        {
            DiffTool tool = alternateTool ? _alternateTwoDiffTool : _selectedTwoDiffTool;
            string args = tool.Arguments;
            args = args.Replace("%theirs%", path1);
            args = args.Replace("%mine%", path2);
            Process.Start(tool.Program, args);
        }

        public void CompareThreeFiles(string path1, string path2, string path3, bool alternateTool)
        {
            DiffTool tool = alternateTool ? _alternateThreeDiffTool : _selectedThreeDiffTool;
            string args = tool.Arguments;
            args = args.Replace("%base%", path1);
            args = args.Replace("%theirs%", path2);
            args = args.Replace("%mine%", path3);
            Process.Start(tool.Program, args);
        }
    }
}
